#include <stdio.h>
#include <stdlib.h>
#include <memory>
#include <exception>
#include "YMessageList.h"

/*TODO: 1.m_pHead->data will always be null,try fix it!
 *		2.GetNextLength should be called before GetData,
 *		  try fix it!
*/

YMessageList::YMessageList()
: m_pHead(nullptr)
, m_pTail(nullptr)
, m_nCount(0)
{}

YMessageList::~YMessageList()
{
	if(m_pHead != nullptr)
		delete m_pHead;
	if(m_pTail != nullptr)
		delete m_pTail;
	m_pHead = nullptr;
	m_pTail = nullptr;
}

int YMessageList::Init()
{
	m_mutex.lock();
	YMessage* message = new YMessage;
	message->pFront = message;
	message->pNext = nullptr;
	message->data = nullptr;
	m_pHead = message;
	m_pTail = message;
	message = nullptr;
	m_mutex.unlock();
	return 0;
}

int YMessageList::AddData(uint8_t* data, int len)
{
	m_mutex.lock();
	YMessage* message = nullptr;
	try
	{
		message = new YMessage;
		message->data = new uint8_t[len];
		
	}
	catch(std::exception& e)
	{
		printf("m_nCount:%d err msg:%s", m_nCount, e.what());
	}
	
	message->len = len;
	memcpy(message->data, data, len);
	
	m_pTail->pNext = message;
	message->pFront = m_pTail;
	message->pNext = nullptr;
	m_pTail = message;
	m_nCount++;
	m_mutex.unlock();
	return 0;
}

int YMessageList::GetData(uint8_t* data, int len)
{
	m_mutex.lock();
	YMessage* message = m_pHead->pNext;
	if(data == nullptr)
	{
		m_mutex.unlock();
		return -1;
	}
	//len = message->len;
	memcpy(data, message->data, len);
	m_pHead->pNext = message->pNext;
	if(message->pNext != nullptr)
	{
		message->pNext->pFront = m_pHead;
	}
	else
	{
		m_pTail = m_pHead;
	}
	delete[] message->data;
	message->data = nullptr;
	delete message;
	message = nullptr;
	m_nCount--;
	m_mutex.unlock();
	return 0;
}

int YMessageList::GetNextLength()
{
	m_mutex.lock();
	int len = 0;
	if(m_pHead != m_pTail)
	{
		len = m_pHead->pNext->len;
	}
	m_mutex.unlock();
	return len;
}
int YMessageList::Release()
{
	m_mutex.lock();
	while(!IsEmpty())
	{
		YMessage* message = m_pHead->pNext;
		m_pHead->pNext = message->pNext;
		delete[] message->data;
		message->data = nullptr;
		delete message;
		message = nullptr;
	}
	m_pHead->pFront = nullptr;
	delete m_pHead;
	m_pHead = nullptr;
	m_pTail = nullptr;
	m_mutex.unlock();
	return 0;
}


bool YMessageList::IsEmpty()
{
	return (m_pHead->pNext == nullptr);
}

int YMessageList::GetCount()
{
	return m_nCount;
}





